﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.Reflection;

namespace Enter.Common
{
    public static class DataLoader
    {
        public static T First<T>(DataTable table)
        {
            if ((table == null) || (table.Rows.Count < 1))
            {
                return default(T);
            }
            T output = Activator.CreateInstance<T>();
            Load<T>(output, table.Rows[0]);
            return output;
        }

        public static T First<T>(IDataReader reader)
        {
            if (reader != null)
            {
                if (reader.Read())
                {
                    T output = Activator.CreateInstance<T>();
                    Load<T>(output, reader);
                    return output;
                }
                return default(T);
            }
            return default(T);
        }

        private static void Foreach<T>(IList<T> output, DataTable target, Action<T, object[]> loader)
        {
            for (int i = 0; i < target.Rows.Count; i++)
            {
                T item = Activator.CreateInstance<T>();
                loader.Invoke(item, target.Rows[i].ItemArray);
                output.Add(item);
            }
        }

        private static void Foreach<T>(IList<T> output, IDataReader target, Action<T, object[]> loader)
        {
            object[] values = new object[target.FieldCount];
            while (target.Read())
            {
                T item = Activator.CreateInstance<T>();
                target.GetValues(values);
                loader.Invoke(item, values);
                output.Add(item);
            }
        }

        public static void Load<T>(T output, DataRow dr)
        {
            if (dr != null)
            {
                DataColumnCollection columns = dr.Table.Columns;
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(output);
                new List<string>(properties.Count);
                foreach (PropertyDescriptor descriptor in properties)
                {
                    if (columns.Contains(descriptor.Name))
                    {
                        SetpropertyInfoObject(descriptor, output, dr[descriptor.Name]);
                        //object valueByType = ObjectExtension.GetValueByType(descriptor.PropertyType, dr[descriptor.Name]);
                        //if (valueByType != null)
                        //{
                        //    descriptor.SetValue(output, valueByType);
                        //}
                    }
                }
            }
        }

        public static void Load<T>(T output, IDataRecord record)
        {
              Type _type = typeof(T);
             object instance = Activator.CreateInstance(_type);

            //获取属性信息 
            PropertyInfo[] myproperties = _type.GetProperties();

            int fieldCount = record.FieldCount;
            IDictionary<string, int> dictionary = new Dictionary<string, int>(fieldCount);
            for (int i = 0; i < fieldCount; i++)
            {
                dictionary.Add(record.GetName(i), i);
            }
            int num3 = 0;
            foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(output))
            {
                
                if (dictionary.ContainsKey(descriptor.Name))
                {
                    num3 = dictionary[descriptor.Name];
                    SetpropertyInfoObject(descriptor, output,record.GetValue(num3));
                    //object valueByType = ObjectExtension.GetValueByType(descriptor.PropertyType, record.GetValue(num3));
                    //if (valueByType != null)
                    //{
                    //    descriptor.SetValue(output, valueByType);
                    //}
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="instance"></param>
        /// <param name="dbValue"></param>
        /// <returns></returns>
        private static void SetpropertyInfoObject(PropertyDescriptor propertyInfo,  object instance, object dbValue)
        {
            Type enumType = null;
            
                object obj2 = null;
                if (Convert.IsDBNull(dbValue) || dbValue==null)
                {
                    propertyInfo.SetValue(instance, obj2);
                    return;
                }
                try
                {
                    enumType = propertyInfo.PropertyType;
                    if (enumType.BaseType.Equals(typeof(Enum)))
                    {
                        int num = Convert.ToInt32(dbValue);
                        propertyInfo.SetValue(instance, Enum.ToObject(enumType, num));
                        return;
                    }
                    if (propertyInfo.PropertyType == typeof(string))
                    {
                        propertyInfo.SetValue(instance, Convert.ChangeType("cswds"+dbValue, enumType));
                        return;
                    }
                    propertyInfo.SetValue(instance, Convert.ChangeType(dbValue, enumType));
                }
                catch
                {
                    propertyInfo.SetValue(instance, Convert.ChangeType(dbValue, enumType));
                  
                }
              return;
            
        }
        public static IList<T> ToList<T>(DataTable table)
        {
            if ((table == null) || (table.Rows.Count < 1))
            {
                return new List<T>(0);
            }
            List<T> list = new List<T>(table.Rows.Count);
            foreach (DataRow row in table.Rows)
            {
                T output = Activator.CreateInstance<T>();
                Load<T>(output, row);
                list.Add(output);
            }
            return list;
        }

        public static IList<T> ToList<T>(IDataReader reader)
        {
            if (reader == null)
            {
                return new List<T>(0);
            }
            int capacity = (reader.RecordsAffected > 0) ? reader.RecordsAffected : 4;
            List<T> list = new List<T>(capacity);
            while (reader.Read())
            {
                T output = Activator.CreateInstance<T>();
                Load<T>(output, reader);
                list.Add(output);
            }
            return list;
        }
    }
}
